<template>
  <div>
    <!--头部： 面包屑导航 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>用户管理</el-breadcrumb-item>
      <el-breadcrumb-item>用户列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!--主体：1. 搜索框、添加用户：Card 卡片  组件：简单卡片：卡片可以只有内容区域-栅格系统-对应element-ui里面的Layout布局 -->
    <!-- 1.Card 卡片使用组件时去掉遍历循环样式及类名根据需要  面包屑导航在global.css里面设置下外边距 -->
    <!-- 2. <el-card>里包含的标签<div>列表内容 </div> 替换成Layout布局组件 分栏间隔：Row 组件 提供 gutter 属性来指定每一栏之间的间隔，默认间隔为 0-->
    <!-- 卡片视图区域 -->
    <el-card>
      <!-- 搜索、添加区域 -->
      <el-row :gutter="20">
        <!-- :span代表列值6是24等分中的6份 复制<el-col :span="8">添加标签 Button按钮里面蓝色按钮标签<el-button type="primary"> -->
        <el-col :span="8">
          <el-input placeholder="请输入搜索内容" v-model="queryInfo.query" clearable @clear="getQueryList">
            <el-button slot="append" icon="el-icon-search" @click="getQueryList"></el-button>
          </el-input>
        </el-col>
        <el-col :span="6">
          <el-button type="primary" @click="addDialogVisible=true">添加用户</el-button>
        </el-col>
      </el-row>
      <!-- 主体：2.表格-Tabel组件-基础表格 -->
      <!-- 当el-table元素中注入data对象数组后，在el-table-column中用prop属性来对应对象中的键名即可填入数据，
      用label属性来定义表格的列名。可以使用width属性来定义列宽。-->
      <template>
        <!-- :data="tableData"该成实际:data="userList" 左边data绑定数据源 右边userList是data数据中的数据，数据类型是数组 prop填入后台数据-->
        <!-- stripe添加隔行变色效果 border添加边框线 -->
        <el-table :data="userList" style="width: 100%" stripe border>
          <el-table-column type="index" width="50"></el-table-column>
          <el-table-column prop="username" label="姓名" width="180"></el-table-column>
          <el-table-column prop="email" label="邮箱" width="180"></el-table-column>
          <el-table-column prop="mobile" label="电话"></el-table-column>
          <el-table-column prop="role_name" label="角色"></el-table-column>
          <el-table-column prop="mg_state" label="状态">
            <!-- 状态mg_state是布尔值在页面上看不到 通过按钮形式让状态显示   应用作用域插槽  在Switch开关中找到对应代码<el-switch v-model="value" active-color="#13ce66" inactive-color="#ff4949"></el-switch>  -->
            <!-- 作用域插槽使用template标签包裹，该标签不会被DOM渲染 绑定slot-scope属性，属性值为scope，scope也是属性它对应row 行的表头和col列表头通知定义这两个表头 -->
            <template slot-scope="scope">
              <!-- {{scope.row}} -->
              <!-- 将scope.row获取到数据中的 状态作为值value 对这条数据的状态值进行双向数据绑定-->
              <!-- 修改用户状态 Switch组件中方法 change事件 绑定change事件监听用户状态改变（通过v-module指令双向数据绑定switch状态发生改变就把数据双向绑定到mg_state身上 ） 当状态改变就调用API接口 调用函数将状态改变同步到数据库 -->
              <el-switch
                v-model="scope.row.mg_state"
                active-color="primary"
                inactive-color
                @change="stateChange(scope.row)"
              ></el-switch>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="180px">
            <!-- 使用作用域插槽 用template按钮接收按钮-组件Button primary蓝色 danger红色 warning黄色 size属性medium / small / mini控制大小-->
            <!-- with设置操作框的大小 -->
            <template slot-scope="scope">
              <el-button
                type="primary"
                icon="el-icon-edit"
                size="mini"
                @click="showEditDialog(scope.row.id)"
              ></el-button>
              <!-- 删除按钮 -->
              <el-button type="danger" icon="el-icon-delete" size="mini" @click="removeUserById(scope.row.id)"></el-button>
              <!-- 文字提示，鼠标经过（hover）不同按钮上就有提示文本 Tooltip文字提示组件 -->
              <el-tooltip effect="dark" content="角色分配" placement="top" :enterable="false">
                <el-button type="warning" icon="el-icon-setting" size="mini"></el-button>
              </el-tooltip>
            </template>
          </el-table-column>
        </el-table>
      </template>
      <!-- 分页区域 -->
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="queryInfo.pagenum"
        :page-sizes="[1, 2, 5, 7]"
        :page-size="queryInfo.pagesize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
      ></el-pagination>
    </el-card>
    <!-- 添加用户对话框 组件Dialog对话框 -->
    <el-dialog title="添加用户" :visible.sync="addDialogVisible" width="50%" @close="addDialogClose">
      <!-- 内容主体区域 -->
      <el-form
        :model="addForm"
        :rules="addrules"
        ref="ruleFormRef"
        label-width="100px"
        class="demo-ruleForm"
      >
        <el-form-item label="用户名" prop="username">
          <el-input v-model="addForm.username"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input v-model="addForm.password"></el-input>
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="addForm.email"></el-input>
        </el-form-item>
        <el-form-item label="手机" prop="mobile">
          <el-input v-model="addForm.mobile"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="addUser">确 定</el-button>
      </span>
    </el-dialog>
    <!-- 修改用户对话框 -->
    <el-dialog title="修改用户" :visible.sync="editDialogVisible" width="50%" @click="editDialogClosed">
      <el-form
        :model="edits"
        :rules="editsFormRules"
        ref="editsRef"
        label-width="70px"
      >
        <el-form-item label="用户名">
          <el-input v-model="edits.username" disabled></el-input>
        </el-form-item>
         <el-form-item label="邮箱" prop="email">
          <el-input v-model="edits.email"></el-input>
        </el-form-item>
         <el-form-item label="手机" prop="mobile">
          <el-input v-model="edits.mobile"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="editDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="editUserInfo">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import { async } from 'q'
// 获取用户列表数据查看API接口文档 先写基本结构data created methods 在created中发起最基本的数据请求获取数据列表 在methods方法中使用方法
export default {
  data() {
    // 验证邮箱的规则
    var checkEmail = (rule, value, callback) => {
      // 验证邮箱正则表达式
      const regEmail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/
      // 使用test（）方法验证正则表达式是否匹配正则表达式规则
      if (regEmail.test(value)) {
        // 合法的邮箱 就调用回调函数 必须要有return将验证结果返回
        return callback()
      }
      callback(new Error('请输入合法邮箱'))
    }
    // 验证手机号规则
    var checkMobile = (rule, value, callback) => {
      const regMobile = /^(0|86|17951)?(13[0-9]|15[0123456789]|17[678]|18[0-9]|14[57])[0-9]{8}$/
      if (regMobile.test(value)) {
        return callback()
      }
      callback(new Error('请输入合法手机'))
    }
    return {
      queryInfo: {
        //请求数据
        query: '',
        pagenum: 1,
        pagesize: 2
      },
      userList: [],
      total: 0, //默认为0 请求数据成功res中total是4条数据
      addDialogVisible: false,
      addForm: {
        username: '',
        password: '',
        email: '',
        mobile: ''
      },
      addrules: {
        username: [
          { required: true, message: '请输入用户名', trigger: 'blur' },
          {
            min: 3,
            max: 10,
            message: '用户名长度在 3 到 10 个字符',
            trigger: 'blur'
          }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          {
            min: 3,
            max: 10,
            message: '密码长度在 6 到 15 个字符',
            trigger: 'blur'
          }
        ],
        email: [
          { required: true, message: '请输入邮箱', trigger: 'blur' },
          { validator: checkEmail, trigger: 'blur' }
        ],
        mobile: [
          { required: true, message: '请输入手机号', trigger: 'blur' },
          { validator: checkMobile, trigger: 'blur' }
        ]
      },
      // 控制用户对话框的显示与隐藏
      editDialogVisible: false,
      // 查询到用户的信息对象
      edits: {},
      editsFormRules:{
        email:[
          { required: true, message: '请输入邮箱', trigger: 'blur' },
          { validator: checkEmail, trigger: 'blur' } 
        ],
        mobile: [
          { required: true, message: '请输入手机号', trigger: 'blur' },
          { validator: checkMobile, trigger: 'blur' }
        ]
      }
    }
  },
  created() {
    this.getQueryList()
  },
  // 获取用户数据列表 1.根据接口文档 get方式发送数据请求 路径是users 2.在Users组件创建时就获取到数据列表定义方法getQueryList()
  // 2.在methods中使用 getQueryList()方法 先在data中定义数据对象getInfo传递后台提供的数据 再在该方法中使用get请求传递2个参数：请求路径-后台 数据对象pramers：data定义的数据对象
  // 获取到的数据是promise对象 发送ajax数据请求使用await简化.then（）方法，async方法发送异步请求，必须在函数前使用
  methods: {
    async getQueryList() {
      //  var res = await this.$http.get('users',{params:this.queryInfo})
      //  console.log(res);//res的data数据是需要获取的 使用解构赋值简单些   res的data中users是需要获取到的用户列表 需要判断
      const { data: res } = await this.$http.get('users', {
        params: this.queryInfo
      })
      // console.log(res)
      //否则 请求数据成功就在data中定义一个空数组保存响应回来的数据 且定义默认total是0  把请求回来的数据使用赋值方式保存到data中定义的空数组中
      if (res.meta.status !== 200) {
        return this.$message.error('请求失败，获取数据不成功')
      }
      this.userList = res.data.users
      this.total = res.data.total
      // console.log(this.userList);
      // console.log(this.total);
    },
    handleSizeChange(newPageSize) {
      // console.log(newPageSize)
      this.queryInfo.pagesize = newPageSize
      this.getQueryList()
    },
    handleCurrentChange(newPageNumber) {
      // console.log(newPageNumber);
      this.queryInfo.pagenum = newPageNumber
      this.getQueryList()
    },
    async stateChange(infoData) {
      // console.log(infoData) //当状态发生改变时mg_state状态值发生改变
      // 当状态发生改变 调用API接口 发送数据请求 得到promise对象使用async跟await方法 获取需要的数据 然后将数据同步到数据库中
      // this.$http.push(`users/:uId/state/:type`)//  /:uId代表用户ID uId动态数据  /:type type状态 拼接动态参数用反引号拼接
      // const res= this.$http.put(`users/${infoData.id}/state/${infoData.mg_state}`)
      // console.log(res);
      const { data: res } = await this.$http.put(
        `users/${infoData.id}/state/${infoData.mg_state}`
      )
      console.log(res)
      if (res.meta.status !== 200) {
        infoData.mg_state = !infoData.mg_state
        return this.$message.error('状态更新失败') //更新用户状态失败就保持状态不改变
      }
      this.$message.success('更新用户状态成功')
    },
    // 添加用户对话框的关闭事件
    addDialogClose() {
      this.$refs.ruleFormRef.resetFields()
    },
    addUser() {
      this.$refs.ruleFormRef.validate(async vali => {
        // console.log(vali);
        if (!vali) return
        // 可发请求-添加用户的网络请求 调用后台API接口添加用户
        const { data: res } = await this.$http.post('users', this.addForm)
        console.log(res)
        // console.log(this.$http.post('users',this.addForm));
        if (res.meta.status !== 201) {
          this.$message.error('添加用户失败')
        }
        this.$message.success('添加用户成功')
        // 隐藏添加用户按钮-通过  重新刷新用户列表
        this.addDialogVisible = false
        this.getQueryList()
        console.log(this.getQueryList())
      })
    },
    async showEditDialog(id) {
      console.log(id)
      const { data: res } = await this.$http.get('users/' + id)
      if (res.meta.status !== 200) {
        return this.$message.error('查询用户信息失败')
      }
      this.editDialogVisible = true
      this.edits = res.data
    },
    editDialogClosed(){
      // 监听用户修改对话框的关闭事件 使用resetFields()方法
      this.$refs.editsRef.resetFields()
    },
    // 修改用户信息并提交 
    editUserInfo(){
      this.$refs.editsRef.validate(async valid=>{
        if(!valid) return
        // 可发请求-修改用户信息的数据请求 调用后台API接口添加用户
        const { data: res } = await this.$http.put('users/' + this.edits.id,{
        email:this.edits.email , 
        mobile:this.edits.mobile , 
        })
        console.log(res)
        // console.log(this.$http.put('users',this.edits));
        if (res.meta.status !== 200) {
         return this.$message.error('更新用户信息用户失败')
        }
        // 关闭按钮-通过  
        this.editDialogVisible = false
        // 重新刷新用户列表 
        this.getQueryList()
        // console.log(this.getQueryList())
        // 提示更新数据成功
        this.$message.success('更新用户信息成功')
      })
    },
    // 根据id删除对应的用户数据
    async removeUserById(id){
      // 弹框询问用户是否确定删除数据
     const confirmResult = await this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).catch(error=>error)
        // 用户取消删除 返回cancel  会报错 通过.catch()方法捕获取消行为解决错误
        // 用户确定删除 返回confirm
        console.log(confirmResult);
        if(confirmResult!=='confirm'){
        //   return this.$message({
        //   message: '已经取消的删除',
        //   type: 'success'
        // });
         return this.$message.info('已经取消的删除')
        }
        // console.log('确认了删除');  
        const {data:res} = await this.$http.delete('users/' + id)
        if(res.meta.status !== 200){
          return this.$message.error('删除失败')
        }
        this.$message.success('删除成功')
        // 刷新用户列表 直接调用用获取户列表的方法
        this.getQueryList()
    }
  }
}
</script>
<style lang="less" scoped>
</style>